iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
1

這裡一併解說第二層及第三層,第二層利用MAC地址去找尋封包的目的地位置,而第三層IP層主要為路由功能,利用IP地址將封包送達不同網段的IP,路由器和交換機會紀錄IP地址和MAC地址的映射關係。

昨天我們能透過packet, _ = s.recvfrom(65565)取得整段最原始的封包,這時我們來解析他,第二層的header長度固定為14,第三層的header固定為20,如下所示

Eth_header = packet[:14]
Ip_header = packet[14:34]

Eth_header比較好解釋,packet[:6]packet[6:12]分別代表來源Mac Address和目的地Mac Address,但是還是需要decode一下,可以根據github上的ethAddrDecode進行decode再print出人看得懂的MAC address,後面兩位表示要走乙太網什麼協議,具體的協議可以根據https://zh.wikipedia.org/wiki/%E4%BB%A5%E5%A4%AA%E7%B1%BB%E5%9E%8B
例如最典型的0x0800就是IPv4

ip_header雖然長度只有20,也就是20bytes,但是裡面卻蘊含了許多訊息,如下圖所示,8bits = 1byte,所以一行有4個byte
https://ithelp.ithome.com.tw/upload/images/20200917/20130271yecLqyKnu5.png

python提供struct,用來解構和打包二進位的bytes數據,我們用他來解構ip_header的數據
struct.unpack('!BBHHHBBH4s4s' , ip_header)
第一個參數的英文數字的format如下

FORMAT  [C TYPE]            [PYTHON TYPE]    [BYTES]     [NOTES]
x       pad byte            no value        
c       char                string of length    1               1    
b       signed char         integer             1               (3)
B       unsigned char       integer             1               (3)
?       _Bool               bool                1               (1)
h       short               integer             2               (3)
H       unsigned short      integer             2               (3)
i       int                 integer             4               (3)
I       unsigned int        integer             4               (3)
l       long                integer             4               (3)
L       unsigned long       integer             4               (3)
q       long long           integer             8               (2), (3)
Q       unsigned long       long integer        8                (2), (3)
f       float               float               4               (4)
d       double              float               8               (4)
s       char[]              string        
p       char[]              string        
P       void *              integer                             (5), (3)

符號的意思如下

CHARACTER   [BYTE ORDER]            [SIZE]      [ALIGNMENT]
@           native                  native      native
=           native                  standard    none
<           little-endian           standard    none
>           big-endian              standard    none
!           network(=big-endian)    standard    none

所以這個unpack出來後會分別得到IHL_VERSION, TYPE_OF_SERVICE, TOTAL_LEN, PKTID, FRAGMENT_STATUS, TIME_TO_LIVE, PROTOCOL, Checksum, SRC_IP,DEST_IP,快速說一下header裡這些東西的作用
IHL_VERSION:同時包含版本訊息和ip header長度的訊息
TYPE_OF_SERVICE:服務類型,八個bits,一般為八個0,每個bit組合有不同的意思
https://ithelp.ithome.com.tw/upload/images/20200917/20130271QesBq7QAWj.png

  • TOTAL_LEN:封包總長度
  • PKTID:識別碼,通常是為了校驗checksum
  • FRAGMENT_STATUS: 如果要傳輸大封包,能進行切割標記
  • TIME_TO_LIVE:通過了幾個路由器,如果為0則傳輸失敗
  • PROTOCOL:協定,例如tcp協定、icmp協定等等,這和應用層的http、DNS等是不同的,他們包含在這些協定裡
  • Checksum:用來檢錯用的
  • SRC_IP:來源IP地址
  • DEST_IP:目的地IP地址

系列的成果將會放在這:https://github.com/kaichiachen/pytcpdump
文章配合著程式碼有助於學習 :)


上一篇
Day06 如何利用python監聽所有流過的封包?
下一篇
Day08 聊聊ICMP的應用 - ping
系列文
那些年還給老師的TCP/IP五層結構 - 用Python進行網路封包分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言